<?php

namespace Common\Logic;

/**
 * 订单退款部分逻辑
 * @modify trainyao 2016-05-11 创建
 */
class OrderRefundLogic extends \Common\Controller\BaseController {
    
    /**
     * 获取退款信息,并进行筛选分页
     * @modify trainyao 2016-05-18 创建
     * @modify trainyao 2016-06-28 增加房间权限判断
     * @modify wenhui 2017-02-23 增加返回关联订单名称
     * @param  integer   $hotelId   客栈ID
     * @param  integer   $status   退款状态
     * @param  string   $startDate   入住日期区间开始
     * @param  integer   $endDate   入住日期区间结束
     * @param  integer   $mobile   预定人手机号
     * @param  integer   $pageIndex   分页页码
     * @param  integer   $pageSize   分页每页数量
     * @return array              array(
     *                                 info => array(array(), array())
     *                                 page => array(  //分页信息,若不传pageIndex,没有该数组
     *                                     current  当前页码
     *                                     size  每页数目
     *                                     total  总数
     *                                     pageTotal  页数总数
     *                                 )
     *                            )
     */
    public function getInfo($hotelId, $status = null, $startDate = null, $endDate = null, $mobile = null, $pageIndex = null, $pageSize = null) {
        // 取出数据
        $orderRefundModel = D('OrderRefund');
        $orderRefundInfo = $orderRefundModel->getInfoByHotel($hotelId);
        if (empty($orderRefundInfo)) {
            return array('info' => array());
        }

        // status筛选
        if (!is_null($status)) {
            foreach ($orderRefundInfo as $index => $orderRefundInfoItem) {
                if ($orderRefundInfoItem['status'] != $status) {
                    unset($orderRefundInfo[$index]);
                }
            }
            unset($orderRefundInfoItem);
        }
        if (empty($orderRefundInfo)) {
            return array('info' => array());
        }

        // 补充orderRoom信息
        $orderRoomIds = array_unique(array_column($orderRefundInfo, 'orderroom_id'));
        $orderRoomModel = D('OrderRoom');
        $orderRoomInfo = $orderRoomModel->getInfo($orderRoomIds);
        $orderRoomInfo = getArrayValueAsIndex($orderRoomInfo, 'id');

        // 日期筛选
        $orderInfoIds = array();
        $dateFilte = !is_null($startDate) && !is_null($endDate);
        foreach ($orderRefundInfo as $index => &$orderRefundInfoItem) {
            if ($dateFilte) {
                $orderStartDateTimestamp = strtotime($orderRoomInfo[$orderRefundInfoItem['orderroom_id']]['startdate']);
                if (!isBetweenTime($orderStartDateTimestamp, $startDate, $endDate)) {
                    unset($orderRefundInfo[$index]);
                    continue;
                }
            }
            $orderRefundInfoItem['orderRoom'] = $orderRoomInfo[$orderRefundInfoItem['orderroom_id']];
            array_push($orderInfoIds, $orderRoomInfo[$orderRefundInfoItem['orderroom_id']]['orderinfo_id']);
        }
        unset($orderRefundInfoItem);
        if (empty($orderRefundInfo)) {
            return array('info' => array());
        }

        // 补充父订单信息
        $orderInfoIds = array_unique($orderInfoIds);
        $orderInfoModel = D('OrderInfo');
        $orderInfo = $orderInfoModel->getInfo($orderInfoIds);
        if (count($orderInfoIds) == 1) {
            $orderInfo = array($orderInfo);
        }
        $orderInfo = getArrayValueAsIndex($orderInfo, 'id');

        // 预定手机号筛选
        $mobileFilte = !is_null($mobile);
        foreach ($orderRefundInfo as $index => &$orderRefundInfoItem) {
            $orderInfoId = $orderRefundInfoItem['orderRoom']['orderinfo_id'];
            if ($mobileFilte) {
                if ($orderInfo[$orderInfoId]['mobile'] != $mobile) {
                    unset($orderRefundInfo[$index]);
                    continue;
                }
            }
            $orderRefundInfoItem['order'] = $orderInfo[$orderInfoId];
        }
        unset($orderRefundInfoItem);
        if (empty($orderRefundInfo)) {
            return array('info' => array());
        }

        if (MODULE_NAME != 'Extend') {
            // 判断是否有权限查看信息
            $canSeeMobile = true;
            $adminAuthorityLogic = A('Common/AdminAuthority', 'Logic');
            $canSeeMobile = $adminAuthorityLogic->check($hotelId, null, AUTHORITY_CONTACT_INFO_BLOCK);
            if (!$canSeeMobile) {
                foreach ($orderRefundInfo as &$orderRefundInfoItem) {
                    $orderRefundInfoItem['order']['mobile'] = !empty($orderRefundInfoItem['order']['mobile']) ? substr($orderRefundInfoItem['order']['mobile'], 0, 3) . '********' : $orderRefundInfoItem['order']['mobile'];
                }
                unset($orderRefundInfoItem);
            }

            // 判断是否需要根据房间权限
            $adminId = getUserId();
            $adminAuthorityLogic = A('Common/AdminAuthority', 'Logic');
            if (!$adminAuthorityLogic->checkIsAdmin($adminId, $hotelId)) {
                $accountLogic = A('Common/Account', 'Logic');
                $roomAuthority = $accountLogic->getAdminRoomAuthority($adminId, $hotelId);
                foreach ($orderRefundInfo as $index => $orderRefundInfoItem) {
                    if (!in_array($orderRefundInfoItem['orderRoom']['roominfo_id'], $roomAuthority)) {
                        unset($orderRefundInfo[$index]);
                    }
                }
                unset($orderRefundInfoItem);
            }
        }

         // 补充关联订单名称 （根据子订单id 获取父订单id 再根据父订单id 获取所有子订单id）
        $orderRoomInfo = $orderRoomModel->getInfo($orderRoomIds);
        $orderInfoIds = array_column($orderRoomInfo, 'orderinfo_id');
        $orderRoomInfoAll = $orderRoomModel->getInfoByOrder($orderInfoIds, false);
        foreach ($orderRefundInfo as $key => &$orderRefundInfoItem) {
            foreach ($orderRoomInfoAll as $key => $orderRoomInfoItems) {
                if ($orderRefundInfoItem['orderRoom']['orderinfo_id'] == $orderRoomInfoItems['orderinfo_id'] && $orderRefundInfoItem['orderRoom']['id'] != $orderRoomInfoItems['id']) {
                    $orderRefundInfoItem['orderRoom']['roominfo_name'] = $orderRefundInfoItem['orderRoom']['roominfo_name'] . ',' .$orderRoomInfoItems['roominfo_name'];
                }
            }
        }

        // 进行分页
        $orderRefundInfo = $this->generatePageInfo(array_values($orderRefundInfo), $pageIndex, $pageSize);

        // 返回信息
        return $orderRefundInfo;
    }

    /**
     * 生成分页信息
     * @modify trainyao 2016-05-18  创建
     * @param  array   $refundInfo 退款信息数组
     * @param  integer   $pageIndex  页码
     * @param  integer   $pageSize   每页条目数目
     * @return array               信息数组
     */
    private function generatePageInfo($refundInfo, $pageIndex, $pageSize) {
        if (empty($pageIndex) || empty($pageSize)) {
            return array('info' => $refundInfo);
        }

        // 处理分页
        $pageInfo = array();
        $refundInfo = createPageInfo($refundInfo, $pageIndex, $pageSize);
        $pageInfo = array(
            'current' => $refundInfo['current'],
            'size' => $refundInfo['size'],
            'total' => $refundInfo['total'],
            'pageTotal' => $refundInfo['pageTotal'],
        );
        $refundInfo = $refundInfo['data'];

        return array('info' => $refundInfo, 'page' => $pageInfo);
    }

    /**
     * 退款申请
     * 方法会抛异常
     * @modify trainyao 2016-05-17   创建
     * @modify trainyao 2016-06-20 增加代收查询操作
     * @param  integer   $hotelId     客栈ID
     * @param  integer   $orderRoomId 子订单id
     * @param  string   $price        退款申请价格
     * @param  string   $reason      退款理由
     * @return boolean                执行结果
     */ 
    public function refund($hotelId, $orderRoomId, $price, $reason, $type = null, $orderId = null) {
        if (is_null($type)) {
            $type = REFUND_TYPE_APPLY;
        }

        // 如果是提前退房,检查是否有代收记录,若无 并且不是会员卡支付,不进行插表操作
        if ($type == REFUND_TYPE_CHECKOUT) {

            $isVipCardPay = false;
            if (!is_null($orderId)) {
                // 获取支付方式在该客栈的支付方式id
                $hotelLogic = A('Common/Hotel', 'Logic');
                $hotelPay = $hotelLogic->getHotelPay($hotelId, false, 'zh_cn', true);
                $hotelPay = getArrayValueAsIndex($hotelPay, 'name');
                $hotelPayId = $hotelPay['会员卡']['id'];
                $orderPayRecordModel = D('OrderPayRecord');
                $orderPayRecordInfo = $orderPayRecordModel->getInfoByOrderIdAnPayId($orderId, $hotelPayId);
                // 是否有会员卡收款记录
                if (!empty($orderPayRecordInfo)) {
                    $isVipCardPay = true;
                }
            }

            // 检查是否有代收记录,若无 并且不是会员卡支付,不进行插表操作
            $orderPayInfoModel = D('OrderPayInfo');
            $orderPayInfo = $orderPayInfoModel->getInfoByOrderMethod($orderRoomId);
            if (empty($orderPayInfo) && !$isVipCardPay) {
                return true;
            }
        }
        
        // 检查是否已经申请过退款
        $orderRefundModel = D('OrderRefund');
        $orderRefundInfo = $orderRefundModel->getInfoByOrder($orderRoomId);
        if (!empty($orderRefundInfo) && in_array($type, array_column($orderRefundInfo, 'type'))) {
            throw new \Exception('403,202', 202);
            return false;
        }

        // 添加退款记录
        $refundResult = $orderRefundModel->addInfo($hotelId, $orderRoomId, $price, $reason, $type);
        if (empty($refundResult)) {
            throw new \Exception('500,508', 508);
            return false;
        }
        return true;
    }

    /**
     * 同意申请退款逻辑
     * 方法会抛异常
     * @modify trainyao 2016-05-17   创建
     * @modify trainyao 2016-06-22    改为根据退款id操作
     * @param  integer   $refundId 子订单ID
     * @param  string   $refundPrice 已退款价格
     * @param  mixin   $multiTransMode 是否在事务嵌套内
     * @return boolean                执行结果
     */
    public function agreeRefund($refundId, $refundPrice, $multiTransMode = true) {
        // 检查数据是否存在,是否已经处理
        $orderRefundModel = D('OrderRefund');
        $orderRefundInfo = $orderRefundModel->getInfo($refundId);
        if (empty($orderRefundInfo)) {
            throw new \Exception('403,202', 202);
            return false;
        }
        if ($orderRefundInfo['status'] != ORDER_REFUND_APPLY) {
            // 考虑同步操作
            throw new \Exception('200,200', 200);
            return true;
        }

        if ($multiTransMode !== true) {
            $orderRefundModel->startTrans();
        }
        $commit = true;
        // 修改状态
        $agreeResult = $orderRefundModel->saveInfo($refundId, ORDER_REFUND_SUCCESS, $refundPrice, null);
        if (empty($agreeResult)) {
            $commit = false;
        }

        if ($commit) {
            if ($multiTransMode !== true) {
                $orderRefundModel->commit();
            }
            return true;
        } else {
            if ($multiTransMode !== true) {
                $orderRefundModel->rollback();
            }
            throw new \Exception('500,506', 506);
            return false;
        }
    }

    /**
     * 驳回申请退款逻辑
     * 方法会抛异常
     * @modify trainyao 2016-05-17   创建
     * @param  integer   $orderRoomId 子订单ID
     * @param  string   $apply        驳回理由
     * @return boolean                执行结果
     */
    public function refuseRefund($orderRoomId, $apply) {
        // 检查数据是否存在,是否已经处理
        $orderRefundModel = D('OrderRefund');
        $orderRefundInfo = $orderRefundModel->getInfoByOrder($orderRoomId);
        $orderRefundInfo = getArrayValueAsIndex($orderRefundInfo, 'type', 'multi');
        $orderRefundInfo = $orderRefundInfo[REFUND_TYPE_APPLY][0];
        if (empty($orderRefundInfo)) {
            throw new \Exception('403,202', 202);
            return false;
        }
        if ($orderRefundInfo['status'] != ORDER_REFUND_APPLY) {
            // 考虑同步操作
            throw new \Exception('200,200', 200);
            return true;
        }

        // 修改状态
        $refuseResult = $orderRefundModel->saveInfo($orderRefundInfo['id'], ORDER_REFUND_REFUSE, null, $apply);
        if (empty($refuseResult)) {
            throw new \Exception('500,506', 506);
            return false;
        }
        return true;
    }
}
